// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.MachineLearning;

public sealed partial class TrainedModel
{
	/// <summary>
	/// <para>The definition for an ensemble model</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("ensemble")]
	public Elastic.Clients.Elasticsearch.MachineLearning.Ensemble? Ensemble { get; set; }

	/// <summary>
	/// <para>The definition for a binary decision tree.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("tree")]
	public Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTree? Tree { get; set; }

	/// <summary>
	/// <para>The definition of a node in a tree.<br/>There are two major types of nodes: leaf nodes and not-leaf nodes.<br/>- Leaf nodes only need node_index and leaf_value defined.<br/>- All other nodes need split_feature, left_child, right_child, threshold, decision_type, and default_left defined.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("tree_node")]
	public Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNode? TreeNode { get; set; }
}

public sealed partial class TrainedModelDescriptor : SerializableDescriptor<TrainedModelDescriptor>
{
	internal TrainedModelDescriptor(Action<TrainedModelDescriptor> configure) => configure.Invoke(this);

	public TrainedModelDescriptor() : base()
	{
	}

	private Elastic.Clients.Elasticsearch.MachineLearning.Ensemble? EnsembleValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.EnsembleDescriptor EnsembleDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.EnsembleDescriptor> EnsembleDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTree? TreeValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeDescriptor TreeDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeDescriptor> TreeDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNode? TreeNodeValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNodeDescriptor TreeNodeDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNodeDescriptor> TreeNodeDescriptorAction { get; set; }

	/// <summary>
	/// <para>The definition for an ensemble model</para>
	/// </summary>
	public TrainedModelDescriptor Ensemble(Elastic.Clients.Elasticsearch.MachineLearning.Ensemble? ensemble)
	{
		EnsembleDescriptor = null;
		EnsembleDescriptorAction = null;
		EnsembleValue = ensemble;
		return Self;
	}

	public TrainedModelDescriptor Ensemble(Elastic.Clients.Elasticsearch.MachineLearning.EnsembleDescriptor descriptor)
	{
		EnsembleValue = null;
		EnsembleDescriptorAction = null;
		EnsembleDescriptor = descriptor;
		return Self;
	}

	public TrainedModelDescriptor Ensemble(Action<Elastic.Clients.Elasticsearch.MachineLearning.EnsembleDescriptor> configure)
	{
		EnsembleValue = null;
		EnsembleDescriptor = null;
		EnsembleDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The definition for a binary decision tree.</para>
	/// </summary>
	public TrainedModelDescriptor Tree(Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTree? tree)
	{
		TreeDescriptor = null;
		TreeDescriptorAction = null;
		TreeValue = tree;
		return Self;
	}

	public TrainedModelDescriptor Tree(Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeDescriptor descriptor)
	{
		TreeValue = null;
		TreeDescriptorAction = null;
		TreeDescriptor = descriptor;
		return Self;
	}

	public TrainedModelDescriptor Tree(Action<Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeDescriptor> configure)
	{
		TreeValue = null;
		TreeDescriptor = null;
		TreeDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The definition of a node in a tree.<br/>There are two major types of nodes: leaf nodes and not-leaf nodes.<br/>- Leaf nodes only need node_index and leaf_value defined.<br/>- All other nodes need split_feature, left_child, right_child, threshold, decision_type, and default_left defined.</para>
	/// </summary>
	public TrainedModelDescriptor TreeNode(Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNode? treeNode)
	{
		TreeNodeDescriptor = null;
		TreeNodeDescriptorAction = null;
		TreeNodeValue = treeNode;
		return Self;
	}

	public TrainedModelDescriptor TreeNode(Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNodeDescriptor descriptor)
	{
		TreeNodeValue = null;
		TreeNodeDescriptorAction = null;
		TreeNodeDescriptor = descriptor;
		return Self;
	}

	public TrainedModelDescriptor TreeNode(Action<Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNodeDescriptor> configure)
	{
		TreeNodeValue = null;
		TreeNodeDescriptor = null;
		TreeNodeDescriptorAction = configure;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (EnsembleDescriptor is not null)
		{
			writer.WritePropertyName("ensemble");
			JsonSerializer.Serialize(writer, EnsembleDescriptor, options);
		}
		else if (EnsembleDescriptorAction is not null)
		{
			writer.WritePropertyName("ensemble");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.EnsembleDescriptor(EnsembleDescriptorAction), options);
		}
		else if (EnsembleValue is not null)
		{
			writer.WritePropertyName("ensemble");
			JsonSerializer.Serialize(writer, EnsembleValue, options);
		}

		if (TreeDescriptor is not null)
		{
			writer.WritePropertyName("tree");
			JsonSerializer.Serialize(writer, TreeDescriptor, options);
		}
		else if (TreeDescriptorAction is not null)
		{
			writer.WritePropertyName("tree");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeDescriptor(TreeDescriptorAction), options);
		}
		else if (TreeValue is not null)
		{
			writer.WritePropertyName("tree");
			JsonSerializer.Serialize(writer, TreeValue, options);
		}

		if (TreeNodeDescriptor is not null)
		{
			writer.WritePropertyName("tree_node");
			JsonSerializer.Serialize(writer, TreeNodeDescriptor, options);
		}
		else if (TreeNodeDescriptorAction is not null)
		{
			writer.WritePropertyName("tree_node");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.TrainedModelTreeNodeDescriptor(TreeNodeDescriptorAction), options);
		}
		else if (TreeNodeValue is not null)
		{
			writer.WritePropertyName("tree_node");
			JsonSerializer.Serialize(writer, TreeNodeValue, options);
		}

		writer.WriteEndObject();
	}
}